Categories
Buefy

Buefy — Autocomplete Customization

Spread the love

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Header

We can add a custom header to the autocomplete.

To do that, we populate the header slot:

<template>
  <section>
    <b-field label="favorite fruit">
      <b-autocomplete
        rounded
        v-model="name"
        :data="filteredDataArray"
        placeholder="fruit"
        clearable
        ref="autocomplete"
        @select="option => selected = option"
      >
        <template slot="empty">No results found</template>
        <template slot="header">
          <a @click="showAddFruit">
            <span>Add new...</span>
          </a>
        </template>
      </b-autocomplete>
    </b-field>
  </section>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      data: ["apple", "orange", "grape"],
      name: ""
    };
  },
  methods: {
    showAddFruit() {
      this.$buefy.dialog.prompt({
        message: `Fruit`,
        inputAttrs: {
          placeholder: "fruit",
          maxlength: 20,
          value: this.name
        },
        confirmText: "Add",
        onConfirm: value => {
          this.data.push(value);
          this.$refs.autocomplete.setSelected(value);
        }
      });
    }
  },
  computed: {
    filteredDataArray() {
      return this.data.filter(option => {
        return (
          option
            .toString()
            .toLowerCase()
            .indexOf(this.name.toLowerCase()) >= 0
        );
      });
    }
  }
};
</script>

We populate the header slot with a link.

When we click the link, the showAddFruit method is called.

In the method, we show the prompt and set the value to the this.name as the value.

Also, we call this.$refs.autocomplete.setSelected method to set the selected value of the dropdown.

Autocomplete Footer

We can populate the footer slot with the footer.

For example, we can write:

<template>
  <section>
    <b-field label="favorite fruit">
      <b-autocomplete
        rounded
        v-model="name"
        :data="filteredDataArray"
        placeholder="fruit"
        clearable
        ref="autocomplete"
        @select="option => selected = option"
      >
        <template slot="empty">No results found</template>
        <template slot="footer">
          <a @click="showAddFruit">
            <span>Add new...</span>
          </a>
        </template>
      </b-autocomplete>
    </b-field>
  </section>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      data: ["apple", "orange", "grape"],
      name: ""
    };
  },
  methods: {
    showAddFruit() {
      this.$buefy.dialog.prompt({
        message: `Fruit`,
        inputAttrs: {
          placeholder: "fruit",
          maxlength: 20,
          value: this.name
        },
        confirmText: "Add",
        onConfirm: value => {
          this.data.push(value);
          this.$refs.autocomplete.setSelected(value);
        }
      });
    }
  },
  computed: {
    filteredDataArray() {
      return this.data.filter(option => {
        return (
          option
            .toString()
            .toLowerCase()
            .indexOf(this.name.toLowerCase()) >= 0
        );
      });
    }
  }
};
</script>

Now the ‘Add new…’ text is at the bottom of the autocomplete dropdown instead of the top.

Groups

Options can be separated into groups.

For example, we can write:

<template>
  <section>
    <b-field label="favorite fruit">
      <b-autocomplete
        v-model="name"
        group-field="type"
        group-options="items"
        open-on-focus
        :data="filteredDataArray"
        @select="option => (selected = option)"
      >
        <template slot="empty">No results found</template>
      </b-autocomplete>
    </b-field>
  </section>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      data: [
        {
          type: "Fruit",
          items: ["Apple", "Banana", "Watermelon"]
        },
        {
          type: "Vegetables",
          items: ["Carrot", "Broccoli", "Cucumber", "Tomato"]
        }
      ],
      name: ""
    };
  },
  computed: {
    filteredDataArray() {
      const newData = [];
      this.data.forEach(element => {
        const items = element.items.filter(item =>
          item.toLowerCase().includes(this.name.toLowerCase())
        );
        if (items.length) {
          newData.push({ type: element.type, items });
        }
      });
      return newData;
    }
  }
};
</script>

to separate our items into groups and search for them.

We have the group-field which is set to the property for separating the groups.

And group-options has the property with the available items.

The filteredDataArray computed property now has to search the items property instead of the whole this.data array.

Conclusion

We can customize our autocomplete dropdowns in many ways with Buefy.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *